<template>
    <el-table
        v-if="source && source.length !== 0"
        :data="source"
        v-bind="$attrs"
        size="small"
    >
        <template v-for="item in column" :key="item.id">
            <el-table-column v-if="item._useType" v-bind="item" />
            <el-table-column v-else v-bind="item">
                <template #default="{ row, $index }">
                    <el-input
                        v-if="showInputStates[$index][item.prop]"
                        size="small"
                        v-model.lazy="row[item.prop]"
                        @click.stop="onColClick($index, item.prop)"
                    ></el-input>
                    <div
                        v-else
                        style="height: 25px"
                        @click.stop="onColClick($index, item.prop)"
                    >
                        {{ row[item.prop] }}
                    </div>
                </template>
            </el-table-column>
        </template>
    </el-table>
</template>

<script setup>
const props = defineProps({
    modelValue: {
        type: Array,
        default() {
            return [];
        },
    },
    column: {
        type: Array,
        default() {
            return [];
        },
    },
});
const emits = defineEmits(["update:modelValue"]);

let showInputStates = ref([]);
let inputValues = ref([]);
let isInit = ref(true);

const source = computed(() => props.modelValue);
const column = computed(() => {
    return props.column.map((item) => {
        if (/selection|index|expand/.test(item.type)) {
            item._useType = true;
        }
        return item;
    });
});

watch(source, (val) => {
    if (isInit.value) {
        isInit.value = false;
        showInputStates.value = getInitialInputs(val, false);
        inputValues.value = getInitialInputs(val);
    }
});
watch(inputValues, (val) => {
    onChange(val);
});

document.addEventListener("click", () => {
    showInputStates.value.forEach((item) => {
        Object.keys(item).forEach((k) => (item[k] = false));
    });
});

function onColClick(index, prop) {
    showInputStates.value[index][prop] = true;
}
function onChange(val) {
    emits("update:modelValue", val);
}
function getInitialInputs(source, value) {
    return source.map((row) => {
        if (value !== undefined) {
            return Object.keys(row).reduce((res, k) => {
                res[k] = value;
                return res;
            }, {});
        }
        return { ...row };
    });
}
function addRow(e) {
    e.stopPropagation();
    inputValues.value.push(
        column.value.reduce((res, item) => {
            if (item.prop) {
                res[item.prop] = "";
            }
            return res;
        }, {})
    );
    showInputStates.value.push(
        column.value.reduce((res, item) => {
            if (item.prop) {
                res[item.prop] = true;
            }
            return res;
        }, {})
    );
}
defineExpose({
    addRow,
});
</script>

<style></style>
